﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using monitor_2_DBwork;

namespace monitor_server_2_WPF
{
    /// <summary>
    /// Логика взаимодействия для LogWindow.xaml
    /// </summary>
    public partial class LogWindow
    {

        private ObservableCollection<LogData> _logGridItems;
        private bool _closed;

        public LogWindow()
        {
            InitializeComponent();
            //Background = new SolidColorBrush(Res.LighBlack);
        }

        class LogData
        {
            public string Login { get; set; }
            public string Group { get; set; }
            public string Region { get; set; }
            public string Category { get; set; }
            public string EventName { get; set; }
            public DateTime EventTime { get; set; }
        }

        private void CloseMenuItem_OnClick(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private void LogWindow_OnLoaded(object sender, RoutedEventArgs e)
        {
            StatusBar.Background = new SolidColorBrush(Res.NiceBlue);
            SettingsGrid.Background = new SolidColorBrush(Res.LighBlack);
            MainGrid.Background = new SolidColorBrush(Res.LighBlack);
            RecordsCountLabel.Text = Res.Rm.GetString("RecordsCount") + ':';
            RecordsCountBox.Text = "0";

            Title = Res.Rm.GetString("ServerLog");
            CloseMenuItem.Header = Res.Rm.GetString("Close");
            CategoryLabel.Content = Res.Rm.GetString("Category");
            AccessLabel.Content = Res.Rm.GetString("Access");
            RegionLabel.Content = Res.Rm.GetString("Region");
            UserLabel.Content = Res.Rm.GetString("UserName");
            EventLabel.Content = Res.Rm.GetString("Event");
            StartTimeLabel.Content = Res.Rm.GetString("StartTime");
            EndTimeLabel.Content = Res.Rm.GetString("EndTime");
            RefreshButton.Content = new MyDockPanel(Res.GetBitMapFromPng("refresh_alone_16"), Res.Rm.GetString("Refresh"));
            AllCategoryBox.Content = Res.Rm.GetString("All");
            LoginCategoryBox.Content = Res.Rm.GetString("Clients");
            InformationCategoryBox.Content = Res.Rm.GetString("Info");
            WarningCategoryBox.Content = Res.Rm.GetString("Warning");
            AllAccessBox.Content = Res.Rm.GetString("All");
            AdminAccessBox.Content = Res.Rm.GetString("Administrator");
            UserAccessBox.Content = Res.Rm.GetString("User");
            RegionCheckBox.Content = Res.Rm.GetString("Contains");
            UserCheckBox.Content = Res.Rm.GetString("Contains");
            EventCheckBox.Content = Res.Rm.GetString("Contains");
            StartTime.Value = DateTime.Today;
            EndTime.Value = DateTime.Today.AddDays(1);

            var lgc1 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("UserName"),
                Width = 155,
                Binding = new Binding("Login")
            };
            var lgc2 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("Access"),
                Width = 110,
                Binding = new Binding("Group")
            };
            var lgc3 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("Region"),
                Width = 100,
                Binding = new Binding("Region")
            };
            var lgc4 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("Category"),
                Width = 100,
                Binding = new Binding("Category")
            };
            var lgc5 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("Event"),
                Width = 270,
                Binding = new Binding("EventName")
            };
            var lgc6 = new DataGridTextColumn
            {
                Header = Res.Rm.GetString("Date"),
                Width = 140,
                Binding = new Binding("EventTime"),
            };
            LogGrid.Columns.Add(lgc1);
            LogGrid.Columns.Add(lgc2);
            LogGrid.Columns.Add(lgc3);
            LogGrid.Columns.Add(lgc4);
            LogGrid.Columns.Add(lgc5);
            LogGrid.Columns.Add(lgc6);
            LogGrid.AutoGenerateColumns = false;
            LogGrid.CanUserAddRows = false;
            LogGrid.CanUserDeleteRows = false;
            LogGrid.IsReadOnly = true;
            _logGridItems = new ObservableCollection<LogData>();
            LogGrid.ItemsSource = _logGridItems;
            LogGrid.Items.SortDescriptions.Add(new SortDescription("EventTime", ListSortDirection.Descending));
        }

        private void UpdateGrid()
        {
            
        }

        public bool IsClosed
        {
            get { return _closed; }
        }

        public void ShowUp()
        {
            //if(Visibility != Visibility.Visible)
                Visibility = Visibility.Visible;
            if(WindowState == WindowState.Minimized)
                WindowState = WindowState.Normal;
            Activate();
            UpdateGrid();
        }

        private void LogWindow_OnClosed(object sender, EventArgs e)
        {
            _closed = true;
        }

        private void RefreshButton_Click(object sender, RoutedEventArgs e)
        {
            DateTime dt1;
            DateTime dt2;
            Dictionary<string, List<string>> dict;
            const int loginIndex = 0;
            const int accessIndex = 1;
            const int regionIndex = 2;
            const int categoryIndex = 3;
            const int eventIndex = 4;
            const int eventTimeIndex = 5;
            string criteria;
            try
            {
                //Фильтр для запроса записей с сервера
                criteria = MakeFilter(out dt1, out dt2, out dict);
            }
            catch (Exception ex)
            {
                if (ex.Message.Equals("no_start_time"))
                    MessageBox.Show(Res.Rm.GetString("InputValue") + ": " + Res.Rm.GetString("StartTime"));
                if (ex.Message.Equals("no_end_time"))
                    MessageBox.Show(Res.Rm.GetString("InputValue") + ": " + Res.Rm.GetString("EndTime"));
                return;
            }

            var log = DBwork.GetServerLogList(dt1, dt2, -1, criteria, dict);
            var logCollection = new ObservableCollection<LogData>();    //Коллекция записей для отображения
            foreach (var record in log)
            {
                var split = record.Split(';');
                var logRecord = new LogData
                    {
                        Login = split[loginIndex],
                        Group = split[accessIndex],
                        Region = split[regionIndex],
                        Category = split[categoryIndex],
                        EventName = split[eventIndex],
                        //EventTime = DateTime.ParseExact(split[eventTimeIndex], "MM/DD/YYYY HH:MM:ss", CultureInfo.InvariantCulture)
                        EventTime = DateTime.ParseExact(split[eventTimeIndex], "G", CultureInfo.InvariantCulture)
                    };
                logCollection.Add(logRecord);
            }
            LogGrid.ItemsSource = logCollection;
            RecordsCountBox.Text = LogGrid.Items.Count.ToString(CultureInfo.InvariantCulture);
        }

        private void CheckBox_OnChecked(object sender, RoutedEventArgs e)
        {
            var cb = sender as CheckBox;
            cb.Content = Res.Rm.GetString("Equal");
        }

        private void CheckBox_OnUnchecked(object sender, RoutedEventArgs e)
        {
            var cb = sender as CheckBox;
            cb.Content = Res.Rm.GetString("Contains");
        }

        
        private string MakeFilter(out DateTime dt1, out DateTime dt2, out Dictionary<string, List<string>> pars)
        {
            pars = new Dictionary<string, List<string>>();

            var sb = new StringBuilder();
            var users = UserBox.Text.Split('\r');
            if (users.Length > 0)
            {
                for (int i = 1; i < users.Length; i++)
                {
                    users[i] = users[i].Remove(0, 1);
                }
                if (UserCheckBox.IsChecked == false)
                {
                    int i = 0;
                    foreach (var user in users)
                    {
                        if(user == string.Empty)
                            continue;
                        var ulist = new List<string>();
                        if (i == 0)
                            sb.Append(" AND sl.Login LIKE :user" + i.ToString(CultureInfo.InvariantCulture));
                        else
                            sb.Append(" OR sl.Login LIKE :user" + i.ToString(CultureInfo.InvariantCulture));
                        ulist.Add("%" + user + "%");
                        pars.Add("user" + i.ToString(CultureInfo.InvariantCulture), ulist);
                        i++;
                    }
                }
                else
                {
                    sb.Append(" AND sl.Login IN (:users)");
                    var ulist = users.ToList();
                    pars.Add("users", ulist);
                }
            }
            var regions = RegionBox.Text.Split('\r');
            if (regions.Length > 0)
            {
                for (int i = 1; i < regions.Length; i++)
                {
                    regions[i] = regions[i].Remove(0, 1);
                }
                if (RegionCheckBox.IsChecked == false)
                {
                    int i = 0;
                    foreach (var region in regions)
                    {
                        if(region == string.Empty)
                            continue;
                        var rlist = new List<string>();
                        if (i == 0)
                            sb.Append(" AND sl.Oblast.Name LIKE :region" + i.ToString(CultureInfo.InvariantCulture));
                        else
                            sb.Append(" OR sl.Oblast.Name LIKE :region" + i.ToString(CultureInfo.InvariantCulture));
                        rlist.Add("%" + region + "%");
                        pars.Add("region" + i.ToString(CultureInfo.InvariantCulture), rlist);
                        i++;
                    }
                }
                else
                {
                    sb.Append(" AND sl.Oblast.Name IN (:regions)");
                    var rlist = regions.ToList();
                    pars.Add("regions", rlist);
                }
            }
            var events = EventBox.Text.Split('\r');
            if (events.Length > 0)
            {
                for (int i = 1; i < events.Length; i++)
                {
                    events[i] = events[i].Remove(0, 1);
                }
                if (EventCheckBox.IsChecked == false)
                {
                    int i = 0;
                    foreach (var ev in events)
                    {
                        if(ev == string.Empty)
                            continue;
                        var elist = new List<string>();
                        if (i == 0)
                            sb.Append(" AND sl.Name LIKE :ev" + i.ToString(CultureInfo.InvariantCulture));
                        else
                            sb.Append(" OR sl.Name LIKE :ev" + i.ToString(CultureInfo.InvariantCulture));
                        elist.Add("%" + ev + "%");
                        pars.Add("ev" + i.ToString(CultureInfo.InvariantCulture), elist);
                        i++;
                    }
                }
                else
                {
                    sb.Append(" AND sl.Name IN (:events)");
                    var elist = new List<string>();
                    foreach (var @event in events)
                    {
                        elist.Add(@event);
                    }
                    pars.Add("events", elist);
                }
            }

            //Добавление типов доступа к критериям
            {
                
                if (AllAccessBox.IsChecked == true)
                {
                    sb.Append(" AND sl.Idaccess IN (:access)");
                    pars.Add("access", new List<string>(2)
                        {
                            "1",
                            "2"
                        });
                }
                else if(AdminAccessBox.IsChecked == true || UserAccessBox.IsChecked == true)
                {
                    sb.Append(" AND sl.Idaccess IN (:access)");
                    var alist = new List<string>();
                    if(AdminAccessBox.IsChecked == true)
                        alist.Add("1");
                    if(UserAccessBox.IsChecked == true)
                        alist.Add("2");
                    pars.Add("access", alist);
                }
            }

            //Добавление категорий к критериям
            {

                if (AllCategoryBox.IsChecked == true)
                {
                    sb.Append(" AND sl.Idcategory IN (:categories)");
                    pars.Add("categories", new List<string>(3)
                        {
                            "1",
                            "2",
                            "3"
                        });
                }
                else if (LoginCategoryBox.IsChecked == true || InformationCategoryBox.IsChecked == true || WarningCategoryBox.IsChecked == true)
                {
                    sb.Append(" AND sl.Idcategory IN (:categories)");
                    var clist = new List<string>();
                    if (LoginCategoryBox.IsChecked == true)
                        clist.Add("1");
                    if (InformationCategoryBox.IsChecked == true)
                        clist.Add("2");
                    if (WarningCategoryBox.IsChecked == true)
                        clist.Add("3");
                    pars.Add("categories", clist);
                }
            }

            sb.Append(" AND sl.Idcategory != 4 order by Date desc");

            if (StartTime.Value == null)
            {
                throw new Exception("no_start_time");
            }
            if (EndTime.Value == null)
            {
                throw new Exception("no_end_time");
            }
            dt1 = (DateTime)StartTime.Value;
            dt2 = (DateTime)EndTime.Value;
            return sb.ToString();
        }
        

        
    }
}
